home *** CD-ROM | disk | FTP | other *** search
- head 1.4;
- access;
- symbols
- VER_0_3:1.4
- VER_0_2:1.3;
- locks; strict;
- comment @ * @;
-
-
- 1.4
- date 95.03.24.11.44.17; author coulter; state Exp;
- branches;
- next 1.3;
-
- 1.3
- date 95.03.10.02.43.06; author coulter; state Exp;
- branches;
- next 1.2;
-
- 1.2
- date 95.02.13.20.56.00; author coulter; state Exp;
- branches;
- next 1.1;
-
- 1.1
- date 95.02.11.13.13.24; author coulter; state Exp;
- branches;
- next ;
-
-
- desc
- @isofs directory handling functions. Will add call to iso_ioctl.
- @
-
-
- 1.4
- log
- @Checkin version for 0.3 distribution.
- @
- text
- @/*
- * linux/fs/isofs/dir.c
- *
- * Copyright 1995 Michael Coulter for access logging.
- *
- * (C) 1992, 1993, 1994 Eric Youngdale Modified for ISO9660 filesystem.
- *
- * (C) 1991 Linus Torvalds - minix filesystem
- *
- * isofs directory handling functions
- */
-
- #include <linux/errno.h>
-
- #include <asm/segment.h>
-
- #include <linux/fs.h>
- #include <linux/iso_fs.h>
- #include <linux/kernel.h>
- #include <linux/stat.h>
- #include <linux/string.h>
- #include <linux/mm.h>
- #include <linux/malloc.h>
- #include <linux/sched.h>
- #include <linux/locks.h>
-
- #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
- #define ROUND_UP(x) (((x)+3) & ~3)
-
- static int isofs_readdir(struct inode *, struct file *, struct dirent *, int);
-
- static struct file_operations isofs_dir_operations = {
- NULL, /* lseek - default */
- NULL, /* read */
- NULL, /* write - bad */
- isofs_readdir, /* readdir */
- NULL, /* select - default */
- iso_ioctl, /* ioctl */
- NULL, /* no special open code */
- NULL, /* no special release code */
- NULL /* fsync */
- };
-
- /*
- * directories can handle most operations...
- */
- struct inode_operations isofs_dir_inode_operations = {
- &isofs_dir_operations, /* default directory file-ops */
- NULL, /* create */
- isofs_lookup, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- NULL, /* readlink */
- NULL, /* follow_link */
- isofs_bmap, /* bmap */
- NULL, /* truncate */
- NULL /* permission */
- };
-
- static int isofs_readdir(struct inode * inode, struct file * filp,
- struct dirent * dirent, int count)
- {
- unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
- unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
- unsigned int block,offset,i, j;
- char c = 0;
- int inode_number;
- struct buffer_head * bh;
- void * cpnt = NULL;
- unsigned int old_offset;
- int dlen, rrflag;
- char * dpnt, *dpnt1;
- struct iso_directory_record * de;
-
- iso_log_add(inode->i_ino, inode->i_dev, ISO_LOG_OP_isofs_readdir);
- dpnt1 = NULL;
- if (!inode || !S_ISDIR(inode->i_mode))
- return -EBADF;
-
- offset = filp->f_pos & (bufsize - 1);
- block = isofs_bmap(inode,filp->f_pos>>bufbits);
-
- if(!block) return 0;
-
- if(!(bh = breada(inode->i_dev, block, bufsize, filp->f_pos, inode->i_size)))
- return 0;
-
- while (filp->f_pos < inode->i_size) {
- #ifdef DEBUG
- printk("Block, offset: %x %x %x\n",
- block, offset, filp->f_pos);
- #endif
- de = (struct iso_directory_record *) (bh->b_data + offset);
- inode_number = (block << bufbits) + (offset & (bufsize - 1));
-
- /* If the length byte is zero, we should move on to the next
- CDROM sector. If we are at the end of the directory, we
- kick out of the while loop. */
-
- if (*((unsigned char *) de) == 0) {
- brelse(bh);
- offset = 0;
- filp->f_pos = ((filp->f_pos & ~(ISOFS_BLOCK_SIZE - 1))
- + ISOFS_BLOCK_SIZE);
- block = isofs_bmap(inode,(filp->f_pos)>>bufbits);
- if (!block
- || !(bh = breada(inode->i_dev, block, bufsize, filp->f_pos,
- inode->i_size)))
- return 0;
- continue;
- }
-
- /* Make sure that the entire directory record is in the
- current bh block.
- If not, we malloc a buffer, and put the two halves together,
- so that we can cleanly read the block */
-
- old_offset = offset;
- offset += *((unsigned char *) de);
- filp->f_pos += *((unsigned char *) de);
-
- if (offset >= bufsize) {
- unsigned int frag1;
- frag1 = bufsize - old_offset;
- cpnt = kmalloc(*((unsigned char *) de),GFP_KERNEL);
- memcpy(cpnt, bh->b_data + old_offset, frag1);
- de = (struct iso_directory_record *) ((char *)cpnt);
- brelse(bh);
- offset = filp->f_pos & (bufsize - 1);
- block = isofs_bmap(inode,(filp->f_pos)>> bufbits);
- if (!block
- || !(bh = breada(inode->i_dev, block, bufsize,
- filp->f_pos, inode->i_size))) {
- kfree(cpnt);
- return 0;
- };
- memcpy((char *)cpnt+frag1, bh->b_data, offset);
- }
-
- /* Handle the case of the '.' directory */
-
- rrflag = 0;
- i = 1;
- if (de->name_len[0] == 1 && de->name[0] == 0) {
- put_fs_byte('.',dirent->d_name);
- inode_number = inode->i_ino;
- dpnt = ".";
- }
-
- /* Handle the case of the '..' directory */
-
- else if (de->name_len[0] == 1 && de->name[0] == 1) {
- put_fs_byte('.',dirent->d_name);
- put_fs_byte('.',dirent->d_name+1);
- i = 2;
- dpnt = "..";
- if((inode->i_sb->u.isofs_sb.s_firstdatazone
- << bufbits) != inode->i_ino)
- inode_number = inode->u.isofs_i.i_backlink;
- else
- inode_number = inode->i_ino;
-
- /* This should never happen, but who knows. Try to be forgiving */
- if(inode_number == -1) {
- inode_number =
- isofs_lookup_grandparent(inode,
- find_rock_ridge_relocation(de, inode));
- if(inode_number == -1){ /* Should never happen */
- printk("Backlink not properly set.\n");
- goto out;
- };
- }
- }
-
- /* Handle everything else. Do name translation if there
- is no Rock Ridge NM field. */
-
- else {
- dlen = de->name_len[0];
- dpnt = de->name;
- i = dlen;
- rrflag = get_rock_ridge_filename(de, &dpnt, &dlen, inode);
- if (rrflag) {
- if (rrflag == -1) { /* This is a rock ridge reloc dir */
- if (cpnt) {
- kfree(cpnt);
- cpnt = NULL;
- };
- continue;
- };
- i = dlen;
- }
- else
- if(inode->i_sb->u.isofs_sb.s_mapping == 'n') {
- dpnt1 = dpnt;
- dpnt = kmalloc(dlen, GFP_KERNEL);
- for (i = 0; i < dlen && i < NAME_MAX; i++) {
- if (!(c = dpnt1[i])) break;
- if (c >= 'A' && c <= 'Z') c |= 0x20; /* lower case */
- if (c == '.' && i == dlen-3 && de->name[i+1] == ';' && de->name[i+2] == '1')
- break; /* Drop trailing '.;1' (ISO9660:1988 7.5.1 requires period) */
- if (c == ';' && i == dlen-2 && de->name[i+1] == '1')
- break; /* Drop trailing ';1' */
- if (c == ';') c = '.'; /* Convert remaining ';' to '.' */
- dpnt[i] = c;
- }
- }
- for(j=0; j<i; j++)
- put_fs_byte(dpnt[j],j+dirent->d_name); /* And save it */
- if(dpnt1) {
- kfree(dpnt);
- dpnt = dpnt1;
- }
-
- dcache_add(inode, dpnt, i, inode_number);
- };
- #if 0
- printk("Nchar: %d\n",i);
- #endif
-
- if (rrflag) kfree(dpnt);
- if (cpnt) {
- kfree(cpnt);
- cpnt = NULL;
- };
-
- if (i) {
- put_fs_long(inode_number, &dirent->d_ino);
- put_fs_byte(0,i+dirent->d_name);
- put_fs_word(i,&dirent->d_reclen);
- brelse(bh);
- return ROUND_UP(NAME_OFFSET(dirent) + i + 1);
- }
- }
- /* We go here for any condition we cannot handle. We also drop through
- to here at the end of the directory. */
- out:
- if (cpnt)
- kfree(cpnt);
- brelse(bh);
- return 0;
- }
-
-
-
- @
-
-
- 1.3
- log
- @Checkin files modified to make version 0.2
- @
- text
- @d3 2
- @
-
-
- 1.2
- log
- @Checkin working version. Try to make it dynamic now.
- @
- text
- @d78 1
- a78 1
- iso_log_add(inode->i_ino, ISO_LOG_OP_isofs_readdir);
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @d36 1
- a36 1
- NULL, /* ioctl - default */
- d78 1
- @
-